/* * (c) Copyright Reserved EVRYTHNG Limited 2016. All rights reserved. * Use of this material is subject to license. * Copying and unauthorised use of this material strictly prohibited. */ package com.evrythng.java.wrapper.core.http; import com.evrythng.java.wrapper.exception.EvrythngClientException; import com.evrythng.java.wrapper.util.JSONUtils; import org.apache.commons.lang3.CharEncoding; import org.apache.http.HttpRequest; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URI; /** * Builder for {@link HttpRequest} methods. */ public final class HttpMethodBuilder { public interface MethodBuilder<T extends HttpRequestBase> { T build(URI uri) throws EvrythngClientException; Method getMethod(); } /** * Enum containing Http methods */ public enum Method { GET, POST, PUT, DELETE } /** * Private constructor, use static methods to create a {@link MethodBuilder} * . */ private HttpMethodBuilder() { } /** * Creates {@link MethodBuilder} for POST request * @param data the content data that will be associated with the POST request * @return the {@link MethodBuilder} instance */ public static MethodBuilder<HttpPost> httpPost(final Object data) { return new EntityMethodBuilder<HttpPost>(Method.POST) { @Override public HttpPost build(final URI uri) throws EvrythngClientException { HttpPost request = new HttpPost(uri); entity(request, data); return request; } }; } /** * Creates {@link MethodBuilder} for multipart POST request * @param file file * @return the {@link MethodBuilder} instance */ public static MethodBuilder<HttpPost> httpPostMultipart(final File file) { return new EntityMethodBuilder<HttpPost>(Method.POST) { @Override public HttpPost build(final URI uri) throws EvrythngClientException { HttpPost request = new HttpPost(uri); MultipartEntity reqEntity = new MultipartEntity(); try { // Name of the file StringBody strBody = new StringBody(file.getName()); reqEntity.addPart("filename", strBody); // File attachment FileBody fileBody = new FileBody(file); reqEntity.addPart("file", fileBody); request.setEntity(reqEntity); } catch (UnsupportedEncodingException ex) { throw new EvrythngClientException("Unable to build the multipart post request", ex); } return request; } }; } /** * Creates {@link MethodBuilder} for multipart PUT request * @param file file * @return the {@link MethodBuilder} instance */ public static MethodBuilder<HttpPut> httpPutMultipart(final File file) { return new EntityMethodBuilder<HttpPut>(Method.PUT) { @Override public HttpPut build(final URI uri) throws EvrythngClientException { HttpPut request = new HttpPut(uri); MultipartEntity reqEntity = new MultipartEntity(); try { // Name of the file StringBody strBody = new StringBody(file.getName()); reqEntity.addPart("filename", strBody); // File attachment FileBody fileBody = new FileBody(file); reqEntity.addPart("file", fileBody); request.setEntity(reqEntity); } catch (UnsupportedEncodingException ex) { throw new EvrythngClientException("Unable to build the multipart put request", ex); } return request; } }; } /** * Creates {@link MethodBuilder} for GET request * @return the {@link MethodBuilder} instance */ public static MethodBuilder<HttpGet> httpGet() { return new MethodBuilder<HttpGet>() { @Override public HttpGet build(final URI uri) { return new HttpGet(uri); } @Override public Method getMethod() { return Method.GET; } }; } /** * Creates {@link MethodBuilder} for PUT request * @param data the content data that will be associated with the PUT request * @return the {@link MethodBuilder} instance */ public static MethodBuilder<HttpPut> httpPut(final Object data) { return new EntityMethodBuilder<HttpPut>(Method.PUT) { @Override public HttpPut build(final URI uri) throws EvrythngClientException { HttpPut request = new HttpPut(uri); entity(request, data); return request; } }; } /** * Creates {@link MethodBuilder} for DELETE request * @return the {@link MethodBuilder} instance */ public static MethodBuilder<HttpDelete> httpDelete() { return new MethodBuilder<HttpDelete>() { @Override public HttpDelete build(final URI uri) { return new HttpDelete(uri); } @Override public Method getMethod() { return Method.DELETE; } }; } protected abstract static class EntityMethodBuilder<E extends HttpEntityEnclosingRequestBase> implements MethodBuilder<E> { private Method method; protected EntityMethodBuilder(final Method method) { this.method = method; } protected void entity(final E request, final Object data) throws EvrythngClientException { try { request.setEntity(new StringEntity(JSONUtils.write(data), CharEncoding.UTF_8)); } catch (Exception e) { // Convert to custom exception: throw new EvrythngClientException("Unable to define request entity: [data={}]", e); } } @Override public Method getMethod() { return method; } } }